
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import javax.management.timer.Timer;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import ece.edt.CASClient;
import ece.edt.HyperPlanning;
import ece.edt.HyperPlanningDB;
import ece.edt.Schedule;
import ece.edt.HyperPlanning.User;
import ece.edt.exceptions.CASClientException;
import ece.edt.exceptions.HyperPlanningException;

public class Grab extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger log = Logger.getLogger(Grab.class);
	
	private String login;
	private String password;
	private String webauth;
	private String service;
	
	private CASClient casClient;
	private Connection connection;
	private HyperPlanning hp;
	
	private boolean use_database;
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String userName = request.getParameter("user");
		String type = request.getParameter("type") == null ? "ical" : request.getParameter("type");
		boolean getAvailableWeeks = request.getParameter("more") == null ? false : !request.getParameter("more").equals("no");

		if (StringUtils.isNotBlank(userName)) {
			try {
				String output;
				User user = hp.getUser(userName);
				Schedule s = hp.grab(user, getAvailableWeeks);
				
				response.setCharacterEncoding("UTF-8");
				PrintWriter writer = response.getWriter();
				
				DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US);
				df.setTimeZone(TimeZone.getTimeZone("GMT"));
				response.setHeader("Expires", df.format(new Date((new Date()).getTime() + 3*Timer.ONE_HOUR)));
				
				if(type.equals("rss")){
					response.setContentType("application/rss+xml; charset=UTF-8");
					output = s.exportAsRSS();
				}else if(type.equals("text")){
					response.setContentType("text/plain; charset=UTF-8");
					output = s.exportAsText();
				}else if(type.equals("txt")){
					response.setContentType("text/plain; charset=UTF-8");
					output = s.exportAsIcal(false);
				}else if(type.equals("ical_2003")){
					response.setHeader("Content-Disposition", "attachment; filename=" + user.getName().split(" ")[0] + ".ics");
					response.setContentType("text/calendar");
					output = s.exportAsIcal(true);
				}else{
					response.setHeader("Content-Disposition", "attachment; filename=" + user.getName().split(" ")[0] + ".ics");
					response.setContentType("text/calendar");
					output = s.exportAsIcal(false);
				}
				//output = new String(output.getBytes("ISO-8859-1"), "UTF-8");
				writer.print(output);
			} catch (Exception e) {
				log.error(request.getQueryString() + " -> " + e.getMessage());
			} 
		}
	}

	@Override
	public void destroy() {
		super.destroy();
		if(use_database){
			try {
				((HyperPlanningDB)hp).closeConnection();
			} catch (SQLException e) {
				log.error(e, e);
			}
		}
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		
		ServletContext conf = config.getServletContext();
		login = conf.getInitParameter("cas-login");
		password = conf.getInitParameter("cas-password");
		webauth = conf.getInitParameter("cas-webauth");
		service = conf.getInitParameter("cas-service");
		use_database = Boolean.parseBoolean(conf.getInitParameter("use_database"));
		
		if(use_database){
			try {
				Context ctx = new InitialContext();
				DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/edtgrabber");
	
				connection = ds.getConnection();
			} catch (NamingException e) {
				log.error(e, e);
			} catch (SQLException e) {
				log.error(e, e);
			}
		}
		
		try {
			casClient = CASClient.getInstance(webauth, service, login, password);
			if(use_database){
				hp = HyperPlanningDB.getInstance(casClient, connection);
			}else{
				hp = HyperPlanning.getInstance(casClient);
			}
		} catch (CASClientException e) {
			log.error(e);
		} catch (HyperPlanningException e) {
			log.error(e);
		}
	}
}
